<template>
    <div>
        <QuillEditor ref="quillEditor" theme="snow" v-model:content="content" :options="editorOptions"
            contentType="html" @update:content="setValue" :key="changeIndex" />
        <!-- 文件上传按钮 -->
        <input type="file" hidden accept="image/*,video/*" ref="fileBtn" @change="handleUpload" />
    </div>
</template>

<script setup>
import { ref, reactive, toRaw, onMounted, watch } from 'vue';
import { QuillEditor } from '@vueup/vue-quill';
import '@vueup/vue-quill/dist/vue-quill.snow.css';

const props = defineProps({
    modelValue: {
        type: String,
        default: ''
    },
    setConfig: {
        type: Object,
        default: () => ({
            disabled: false,
            placeholder: '请输入内容...',
            requestUrl: '',
        })
    }
});

const emit = defineEmits(['update:modelValue']);

// 双向绑定的文本内容
const content = ref(props.modelValue);

// 更新下标刷新配置
const changeIndex = ref(0)

// Quill 编辑器的配置
const editorOptions = reactive({
    theme: 'snow',
    readOnly: props.setConfig.disabled,
    modules: {
        toolbar: props.setConfig.disabled ? [['bold', 'italic', 'underline', 'strike']] : [
            ['bold', 'italic', 'underline', 'strike'],
            [{ 'size': ['small', false, 'large', 'huge'] }],
            [{ 'font': [] }],
            [{ 'align': [] }],
            [{ 'list': 'ordered' }, { 'list': 'bullet' }],
            [{ 'header': [1, 2, 3, 4, 5, 6] }],
            ['image', 'video'],
            ['link'],
        ],
        clipboard: {
            matchVisual: false,  // 禁用自动将粘贴的内容转换为 HTML
        },
    },
    placeholder: props.setConfig.placeholder,
});

watch(() => props.setConfig.placeholder, (newVal) => {
    editorOptions.placeholder = newVal;
    changeIndex.value += 1;
}, {deep: true})

// 编辑器的 ref
const quillEditor = ref();

// 监听文本变化，返回文本
const setValue = () => {
    let text = toRaw(quillEditor.value).getHTML();
    emit('update:modelValue', text);
};

// 处理文件（图片或视频）
const handleFile = (file, e) => {
    let reader = new FileReader();
    reader.onload = function (event) {
        let base64Data = event.target.result;
        let quill = toRaw(quillEditor.value).getQuill();
        let length = quill.getSelection().index;

        // 插入图片或视频（base64 格式）
        if (file.type.indexOf('image') === 0) {
            quill.insertEmbed(length, 'image', base64Data);
        } else if (file.type.indexOf('video') === 0) {
            quill.insertEmbed(length, 'video', base64Data);
        }
    };
    reader.readAsDataURL(file);
    if (e) e.preventDefault(); // 防止默认粘贴行为
};

// 粘贴事件的处理：支持本地图片、视频文件的粘贴
const handlePaste = (e) => {
    let clipboardData = e.clipboardData;
    let items = clipboardData.items;
    let files = clipboardData.files;

    // 检查粘贴内容是否为文件
    if (items && items.length > 0) {
        for (let i = 0; i < items.length; i++) {
            let item = items[i];
            if (item.type.indexOf('image') === 0 || item.type.indexOf('video') === 0) {
                let file = item.getAsFile();
                handleFile(file, e);
                return;
            }
        }
    } else if (files && files.length > 0) {
        // 如果 items 为空，检查 files
        for (let i = 0; i < files.length; i++) {
            let file = files[i];
            if (file.type.indexOf('image') === 0 || file.type.indexOf('video') === 0) {
                handleFile(file, e);
                return;
            }
        }
    }
};

// 图片上传
const handleUpload = (e) => {
    let files = e.target.files;
    if (!files || files.length === 0) return;

    let file = files[0];
    handleFile(file);
};

// 初始化时设置粘贴事件监听
onMounted(() => {
    let quill = toRaw(quillEditor.value).getQuill();
    quill.root.addEventListener('paste', handlePaste);

    // 配置图片上传按钮
    let toolbar = quill.getModule('toolbar');
    toolbar.addHandler('image', () => {
        let fileBtn = document.querySelector('input[type="file"]');
        if (fileBtn) fileBtn.click();
    });
});
</script>

<style scoped lang="scss">
:deep(.ql-editor) {
    min-height: 180px;
    max-height: 298px;
}

:deep(.ql-formats) {
    height: 40px;
    line-height: 40px;
}

:deep(.ql-container) {
    max-height: 300px;
    overflow: auto;
}
</style>